home *** CD-ROM | disk | FTP | other *** search
- /*
- * coil.c - Create a coil of n turns between two points in space
- *
- * Alexander Enzmann
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #ifdef MAC
- #include <console.h>
- #endif
- #include "def.h"
- #include "lib.h"
-
- static void
- determine_coil_point(COORD4 *pos, COORD4 *norm,
- double theta, double phi, double r0, double r1, double d0)
- {
- COORD4 v0, v1, vd;
- double len;
-
- /* Center of the coil */
- SET_COORD4(v0, r0 * cos(theta), r0 * sin(theta), d0, 1.0);
-
- /* Point on the coil */
- SET_COORD4(*pos, (r0 + r1 * sin(phi)) * cos(theta),
- (r0 + r1 * sin(phi)) * sin(theta),
- (r1 * cos(phi)) + d0,
- 1.0);
-
- /* Direction from center to point */
- SUB3_COORD(vd, *pos, v0);
- len = lib_normalize_coord3(&vd);
-
- v0.x = r1*cos(phi)*cos(theta);
- v1.x = -(r0 + r1*sin(phi))*sin(theta);
-
- v0.y = r1*cos(phi)*sin(theta);
- v1.y = (r0 + r1*sin(phi))*cos(theta);
-
- v0.z = -r1*sin(phi);
- v1.z = 0.0;
-
- CROSS(*norm, v0, v1);
- len = lib_normalize_coord3(norm);
-
- len = DOT_PRODUCT(*norm, vd);
- if (len < 0.0) {
- norm->x *= -1.0;
- norm->y *= -1.0;
- norm->z *= -1.0;
- }
- norm->w = 0.0;
- }
-
- static void
- generate_coil(COORD4 *start, COORD4 *end,
- int turns, int step_per_turn, int step_per_side,
- double r0, double r1, char *txname)
- {
- int i, j, k;
- COORD4 p0, p[4], n0, n[4];
- COORD4 dir;
- MATRIX trans;
- double dist, u0, u1, v0, v1, d0, d1, len;
- double deltad, deltau, deltav;
-
- SUB3_COORD(dir, *end, *start);
- dist = lib_normalize_coord3(&dir);
-
- /* Coils are sorta complex, so make bounding slabs oriented along
- the direction of the coil */
- lib_output_bounding_slab(&dir);
-
- /* Figure out the transform to get from the parametrically defined
- coil to the start-end line */
- lib_create_canonical_matrix(trans, start, &dir);
-
- deltad = dist / (double)(turns * step_per_turn);
- deltau = 2.0 * PI / (double)step_per_turn;
- deltav = 2.0 * PI / (double)step_per_side;
-
- /* Start generating the triangles in the coil */
- for (i=0,d0=0.0;i<turns;i++) {
- for (j=0;j<step_per_turn;j++,d0+=deltad) {
- d1 = d0 + deltad;
- u0 = (double)j * deltau;
- u1 = u0 + deltau;
- for (k=0;k<step_per_side;k++) {
- v0 = (double)k * deltav;
- v1 = v0 + deltav;
-
- /* Make the vertices of this patch on the coil */
- determine_coil_point(&p0, &n0, u0, v0, r0, r1, d0);
- lib_transform_coord(&p[0], &p0, trans);
- lib_transform_coord(&n[0], &n0, trans);
- determine_coil_point(&p0, &n0, u0, v1, r0, r1, d0);
- lib_transform_coord(&p[1], &p0, trans);
- lib_transform_coord(&n[1], &n0, trans);
- determine_coil_point(&p0, &n0, u1, v1, r0, r1, d1);
- lib_transform_coord(&p[2], &p0, trans);
- lib_transform_coord(&n[2], &n0, trans);
-
- /* Make triangles out of the vertices */
- /* lib_output_polygon(3, &p[0], txname); */
- lib_output_polypatch(3, &p[0], &n[0], txname);
-
- COPY_COORD4(p[1], p[2]); COPY_COORD4(n[1], n[2]);
- determine_coil_point(&p0, &n0, u1, v0, r0, r1, d1);
- lib_transform_coord(&p[2], &p0, trans);
- lib_transform_coord(&n[2], &n0, trans);
- /* lib_output_polygon(3, &p[0], txname); */
- lib_output_polypatch(3, &p[0], &n[0], txname);
- }
- }
- }
- }
-
- static void
- generate_cyl_coil(COORD4 *start, COORD4 *end,
- int turns, int step_per_turn,
- double r0, double r1, char *txname)
- {
- int i, j, k;
- COORD4 p, p0, p1, n0;
- COORD4 dir;
- MATRIX trans;
- double dist, u0, u1, d0, d1, len;
- double deltad, deltau;
-
- SUB3_COORD(dir, *end, *start);
- dist = lib_normalize_coord3(&dir);
-
- /* Coils are sorta complex, so make bounding slabs oriented along
- the direction of the coil */
- lib_output_bounding_slab(&dir);
-
- /* Figure out the transform to get from the parametrically defined
- coil to the start-end line */
- lib_create_canonical_matrix(trans, start, &dir);
-
- deltad = dist / (double)(turns * step_per_turn);
- deltau = 2.0 * PI / (double)step_per_turn;
-
- /* Start generating the cylinders making up the coil */
- for (i=0,d0=0.0;i<turns;i++) {
- for (j=0;j<step_per_turn;j++,d0+=deltad) {
- d1 = d0 + deltad;
- u0 = (double)j * deltau;
- u1 = u0 + deltau;
- determine_coil_point(&p, &n0, u0, 0.0, r0, 0.0, d0);
- lib_transform_coord(&p0, &p, trans);
- p0.w = r1;
- determine_coil_point(&p, &n0, u1, 0.0, r0, 0.0, d1);
- lib_transform_coord(&p1, &p, trans);
- p1.w = r1;
- lib_output_cylcone(&p0, &p1, txname);
- lib_output_sphere(&p0, txname);
- }
- }
- /* Cap the end */
- lib_output_sphere(&p1, txname);
- }
-
- void
- main(int argc, char *argv[])
- {
- COORD4 back_color, coil_color, dir;
- COORD4 center_pt, end_pt, light;
- COORD4 from, at, up;
- char *txname;
-
- MATRIX m1, m2;
-
- #ifdef MAC
- argc = ccommand(&argv);
- #endif
-
- /* output viewpoint */
- SET_COORD(from, 0.0, 3.0,-8.0);
- SET_COORD(at, 0.0, 0.0, 5.0);
- SET_COORD(up, 0.0, 1.0, 0.0);
- lib_output_viewpoint( &from, &at, &up, 30.0, 1.0, 1.0, 256, 256);
-
- /* output background color - dark blue */
- SET_COORD( back_color, 0.039, 0.18, 0.376 ) ;
- lib_output_background_color( &back_color ) ;
-
- /* Output bounding slabs oriented along the coordinate axes */
- SET_COORD(dir, 1.0, 0.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 1.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 0.0, 1.0);
- lib_output_bounding_slab(&dir);
-
- /* output light source */
- SET_COORD( light,-10.0, 10.0,-20.0) ;
- lib_output_light( &light ) ;
- SET_COORD( light, 10.0, 10.0,-20.0) ;
- lib_output_light( &light ) ;
-
- /* output coil color - red */
- SET_COORD( coil_color, 1.0, 0.2, 0.2 ) ;
- txname = lib_output_color(&coil_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0) ;
-
- /* compute and output coil */
- SET_COORD4(center_pt,-1.0,-1.0, 0.0, 1.0);
- SET_COORD4(end_pt, 1.0, 3.0, 4.0, 1.0);
- /* generate_coil(¢er_pt, &end_pt, 5, 12, 6, 1.0, 0.3, txname); */
- generate_cyl_coil(¢er_pt, &end_pt, 5, 12, 1.0, 0.3, txname);
- }
-